import React, { ReactNode, useEffect } from 'react';
import { Button, Col, Form, Input, Row, Select } from 'antd';
import styles from "./index.module.scss";

type SizeType = Parameters<typeof Form>[0]['size'];

interface CustomFormProps {
    formFileds?: { // 搜索字段配置
        name: string // 键
        label: string // label
        allowClear?: boolean // 是否可以清除
        width?: number | string // 自定义宽度
        defaultValue?: any // 默认值
        placeholder?: string
        required?: boolean // 是否必填
        rules?: any[] // 校验规则
        options?: {
            label?: string
            value?: string
        }[] // 下拉选项
        style?: React.CSSProperties // 自定义样式
        render?: () => ReactNode // 自定义渲染
    }[],
    formSize?: "small" | "default" | "large" // 表单大小
    initFormValues?: any, // 初始化表单值
    formLayout?: 'horizontal' | 'vertical' | 'inline' // 表单布局
    showCancelBtn?: boolean,
    showLabel?: boolean,
    onSubmitTxt?: string,
    onCancelTxt?: string,
    onSubmit?: (values: any) => void // 提交事件
    onCancel?: (values?: any) => void
}

const CustomForm: React.FC<CustomFormProps> = ({
    initFormValues,
    formFileds,
    onSubmit,
    formSize = "default",
    onCancel,
    showLabel = true,
    showCancelBtn = true,
    formLayout = "horizontal",
    onSubmitTxt = "提交",
    onCancelTxt = "取消"
}) => {
    const [form] = Form.useForm();

    const [inline, setInline] = React.useState(false);

    useEffect(() => {
        setInline(formLayout === "inline");
        if (initFormValues && Object.keys(initFormValues).length > 0) {
            form.setFieldsValue(initFormValues);
        }
    }, [formLayout, initFormValues]);

    const createFiled = () => {
        if (!formFileds || formFileds.length === 0) return <div></div>
        let items: any = [];
        formFileds.forEach(item => {
            const layoutStyle = formLayout === "inline" ? { width: item.width ?? 200 } : { width: item.width }
            const baseRules = [{ message: `${item.label}不能为空`, required: item.required }];
            items.push(
                <Form.Item
                    wrapperCol={{ flex: "1 0" }}
                    label={showLabel ? item.label : ""}
                    name={item.name}
                    rules={item.rules ? baseRules.concat(item.rules) : baseRules}
                    style={item.style}
                    key={item.name}
                >
                    {
                        item.render ? (
                            item.render()
                        ) : item.options ? (
                            <Select
                                allowClear
                                style={layoutStyle}
                                options={item.options}
                                placeholder={item.placeholder ?? `请选择${item.label}`}
                                defaultValue={item.defaultValue}
                            >
                            </Select>
                        ) : (
                            <Input
                                autoComplete='off'
                                style={layoutStyle}
                                allowClear={item.allowClear}
                                placeholder={item.placeholder ?? `请输入${item.label}`}
                                maxLength={50}
                            />
                        )
                    }
                </Form.Item>
            )
        })

        return inline ? <Row className={styles['form-filed-content']} gutter={[10, 10]}>{items}</Row> : <>{items}</>;
    }

    const handleReset = () => {
        onCancel && onCancel(false);
        form.resetFields();
    }

    const createButton = () => {
        return (
            <Form.Item className={inline ? styles['form-filed-btn-inline'] : ''}>
                <Row justify={inline ? "start" : "center"} gutter={[10, 10]}>
                    <Col span={!inline ? 24 : ""}><Button style={inline ? {} : { width: "100%" }} type='primary' htmlType='submit'>{onSubmitTxt}</Button></Col>
                    {showCancelBtn && <Col><Button onClick={handleReset}>{onCancelTxt}</Button></Col>}
                </Row>
            </Form.Item>
        )
    }

    return (
        <Form
            size={formSize as SizeType}
            className={inline ? styles['form-filed'] : ''}
            layout={formLayout}
            form={form}
            onFinish={onSubmit}
        >
            {createFiled()}
            {createButton()}
        </Form>
    )
}

export default CustomForm;